package cn.huiyunche.base.service.interfaces.impl;

import cn.huiyunche.base.service.enums.*;
import cn.huiyunche.base.service.framework.utils.HYCUtils;
import cn.huiyunche.base.service.interfaces.CWaybillContactsService;
import cn.huiyunche.base.service.interfaces.CWaybillService;
import cn.huiyunche.base.service.interfaces.CWaybillStatusLogService;
import cn.huiyunche.base.service.interfaces.UserService;
import cn.huiyunche.base.service.mappers.*;
import cn.huiyunche.base.service.mappers.ext.CWaybillContactsViewMapper;
import cn.huiyunche.base.service.model.*;
import cn.huiyunche.base.service.model.CWaybillContactsExample.Criteria;
import cn.huiyunche.base.service.vo.UserVo;
import cn.huiyunche.tools.basic.exceptions.BusinessException;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 运单交接人信息
 *
 * @author Administrator
 */
@Service
public class CWaybillContactsServiceImpl implements CWaybillContactsService {

    private static final Logger LOGGER = LoggerFactory.getLogger(CWaybillContactsServiceImpl.class);

    @Autowired
    private CWaybillContactsMapper cWaybillContactsMapper = null;

    @Autowired
    private CWaybillContactsViewMapper cWaybillContactsViewMapper = null;

    @Autowired
    private CWaybillMapper cWaybillMapper = null;

    @Autowired
    private SServiceOrderMapper sServiceOrderMapper = null;

    @Autowired
    private CWaybillDetailMapper cWaybillDetailMapper = null;

    @Autowired
    private CWaybillStatusLogService cWaybillStatusLogService = null;

    @Autowired
    private SServiceOrderTrailMapper sServiceOrderTrailMapper = null;

    @Autowired
    private CWaybillService cWaybillService = null;

    @Autowired
    private UserService userService = null;

    private UserService getUserService() {
        return this.userService;
    }

    private CWaybillService getCWaybillService() {
        return this.cWaybillService;
    }

    private SServiceOrderTrailMapper getSServiceOrderTrailMapper() {
        return this.sServiceOrderTrailMapper;
    }

    private CWaybillStatusLogService getCWaybillStatusLogService() {
        return this.cWaybillStatusLogService;
    }

    private CWaybillContactsMapper getCWaybillContactsMapper() {
        return this.cWaybillContactsMapper;
    }

    private CWaybillContactsViewMapper getCWaybillContactsViewMapper() {
        return this.cWaybillContactsViewMapper;
    }

    private CWaybillMapper getCWaybillMapper() {
        return this.cWaybillMapper;
    }

    private SServiceOrderMapper getSServiceOrderMapper() {
        return this.sServiceOrderMapper;
    }

    private CWaybillDetailMapper getCWaybillDetailMapper() {
        return this.cWaybillDetailMapper;
    }

    /**
     * 单条写入交接人信息
     *
     * @param record
     * @return
     */
    @Override
    public int insertSelective(CWaybillContacts record) {
        try {
            LOGGER.info("insert into cwaybill contacts one params record : {}.", record);
            return this.getCWaybillContactsMapper().insertSelective(record);
        } catch (Exception e) {
            LOGGER.error("insert cwaybill one error : {}.", e);
            throw new BusinessException("单条写入交接人信息异常");
        }
    }

    /**
     * 批量插入交接人信息
     *
     * @param list
     */
    @Override
    public int batchInsert(List<CWaybillContacts> list) {
        try {
            LOGGER.info("batch insert cwaybill params list : {}.", list);
            return this.getCWaybillContactsViewMapper().batchInsert(list);
        } catch (Exception e) {
            LOGGER.error("batch insert cwaybill error : {}.", e);
            throw new BusinessException("批量插入交接人信息异常");
        }
    }

    @Override
    public List<CWaybillContacts> selectContacts(Long waybillId, Integer type) {
        LOGGER.info("selectContacts params waybillId: {}, type: {}", waybillId, type);
        if (waybillId == null) {
            LOGGER.info("waybillid is not null");
            throw new BusinessException("运单ID不能为空");
        }
//		if (0==type) {
//			logger.info("type is not 0");
//			throw new BusinessException("交接单联系人类型不能为空");
//		}
        CWaybillContactsExample example = new CWaybillContactsExample();
        Criteria criteria = example.createCriteria().andWaybillIdEqualTo(waybillId);
        if (null != type) {
            criteria.andTypeEqualTo(type);
        }

        List<CWaybillContacts> contacts = null;
        contacts = this.getCWaybillContactsMapper().selectByExample(example);
        if (CollectionUtils.isNotEmpty(contacts)) {
            contacts.stream().forEach(contact -> contact.setIdno(StringUtils.isNotBlank(contact.getIdno()) == true ? HYCUtils.decryptAppSensitiveInformation(contact.getIdno()) : null));
            return contacts;
        }
        LOGGER.info("selectContacts result record : {}", contacts.size());
        return null;
    }

    @Override
    public int add(CWaybillContacts contacts, SysAdminUser adminUser) throws Exception {
        if (contacts.getType() == null) {
            LOGGER.info("type is not null");
            throw new BusinessException("交接单联系人类型不能为空");
        } else if (StringUtils.isBlank(contacts.getIdno())
                && contacts.getType() != WaybillContactsTypeEnum.DRIVER.getValue()) {
            LOGGER.info("idno is not null");
            throw new BusinessException("身份证号不能为空");
        } else if (StringUtils.isBlank(contacts.getContact())) {
            LOGGER.info("contact is not null");
            throw new BusinessException("联系人不能为空");
        } else if (StringUtils.isBlank(contacts.getLicenseNumner())) {
            LOGGER.info("licenseNumner is not null");
            throw new BusinessException("车牌号不能为空");
        } else if (StringUtils.isBlank(contacts.getPhone())) {
            LOGGER.info("phone is not null");
            throw new BusinessException("联系方式不能为空");
        } else if (contacts.getWaybillId() == null) {
            LOGGER.info("waybillid is not null");
            throw new BusinessException("运单ID不能为空");
        }
        int record = 0;
        boolean bool = false;
        if (StringUtils.isNotBlank(contacts.getIdno())) {
            contacts.setIdno(HYCUtils.encryptBankCard(contacts.getIdno()));
        }
        if (contacts.getId() != null) {
            record = this.getCWaybillContactsMapper().updateByPrimaryKeySelective(contacts);
        } else {
            record = this.getCWaybillContactsMapper().insertSelective(contacts);
            if (WaybillContactsTypeEnum.DRIVER.getValue() == contacts.getType()) {

                // 增加交车人 安排信息
                CWaybillContacts receiptpersonContacts = new CWaybillContacts();
                BeanUtils.copyProperties(contacts, receiptpersonContacts);
                receiptpersonContacts.setType(WaybillContactsTypeEnum.RECEIPTPERSON.getValue());
                this.insertSelective(receiptpersonContacts);
            }
            bool = true;
        }
        // 提车安排
        if (WaybillContactsTypeEnum.DEPARTPERSON.getValue() == contacts.getType()) {
            this.addDepartperson(contacts, adminUser);
        }
        // 发车安排（上报司机信息）
        if (WaybillContactsTypeEnum.DRIVER.getValue() == contacts.getType()) {

            CWaybill cWaybill = this.getCWaybillMapper().selectByPrimaryKey(contacts.getWaybillId());
            if (cWaybill == null) {
                LOGGER.info("Waybill is empty");
                throw new BusinessException("运单为空");
            }
            // 1:运单是否为：“待发车”
            if (WaybillStatusEnum.WAITSTART.getValue() != cWaybill.getStatus()) {
                LOGGER.info("The current state for waybill : {}", cWaybill.getStatus());
                throw new BusinessException("当前运单状态不是“待发车”状态");
            } else {
                // 更新运单状态为：“待交车”
                CWaybill waybill = new CWaybill();
                waybill.setId(contacts.getWaybillId());
                waybill.setStatus(WaybillStatusEnum.WAITCOMPLETE.getValue());
                this.getCWaybillMapper().updateByPrimaryKeySelective(waybill);
                // 写运单状态日志
                CWaybillStatusLog log = new CWaybillStatusLog();
                log.setCategory(StatusCategoryEnum.PROCESS.getValue());
                log.setWaybillId(contacts.getWaybillId());
                log.setStatus(WaybillStatusEnum.WAITCOMPLETE.getValue());
                if (adminUser == null) {
                    UserVo userVo = this.getUserService().getCurrentUserVo();
                    log.setUserId(userVo.getId());
                    log.setUserName(userVo.getUsername());
                } else {
                    log.setUserId(adminUser.getId());
                    log.setUserName(adminUser.getUsername());
                }
                this.getCWaybillStatusLogService().addCWaybillStatusLog(log);
            }
            // 更新服务订单状态为：“已发车”
            CWaybillDetailExample example = new CWaybillDetailExample();
            example.createCriteria().andWaybillIdEqualTo(contacts.getWaybillId());
            List<CWaybillDetail> cDetails = this.getCWaybillDetailMapper().selectByExample(example);
            if (CollectionUtils.isEmpty(cDetails)) {
                LOGGER.info("waybill detail is empty");
                throw new BusinessException("该运单下没有服务订单");
            }
            List<Long> longs = new ArrayList<Long>();
            List<Long> serviceId = new ArrayList<Long>();
            for (CWaybillDetail detail : cDetails) {
                longs.add(detail.getServiceOrderId());
                if (detail.getServiceDispatchTimes() == 1) {
                    serviceId.add(detail.getServiceOrderId());
                }
            }
            SServiceOrderExample serviceOrderExample = new SServiceOrderExample();
            serviceOrderExample.createCriteria().andIdIn(longs);
            List<SServiceOrder> orders = this.getSServiceOrderMapper().selectByExample(serviceOrderExample);
            if (CollectionUtils.isNotEmpty(orders)) {
                for (SServiceOrder order : orders) {
                    // 1:服务订单是否为：“已提车”
                    if (SServiceOrderStatusEnum.HAVE_EXTRACTED.getValue() == order.getStatus()) {
                        order.setStatus(SServiceOrderStatusEnum.HAVE_ISSUSD.getValue());
                        this.getSServiceOrderMapper().updateByPrimaryKeySelective(order);
                    }
                }
            }
            if (bool && serviceId.size() > 0) {
                SServiceOrderExample serviceOrders = new SServiceOrderExample();
                serviceOrders.createCriteria().andIdIn(serviceId);
                List<SServiceOrder> orderList = this.getSServiceOrderMapper().selectByExample(serviceOrders);
                if (CollectionUtils.isNotEmpty(orderList)) {
                    for (SServiceOrder order : orderList) {
                        SServiceOrderTrail trail = new SServiceOrderTrail();
                        trail.setInfo(SServiceOrderStatusEnum.getByValue(order.getStatus()).getText());
                        trail.setServiceOrderId(order.getId());
                        trail.setStatus(SServiceOrderStatusEnum.getByValue(order.getStatus()).getValue());
                        trail.setType(SServiceOrderTrailTypeEnum.SERVICE_ORDER_STATUS.getValue());
                        // 写入服务订单物流信息
                        this.getSServiceOrderTrailMapper().insertSelective(trail);
                    }
                }
            }
        }
        return record;
    }

    /**
     * 提车安排
     *
     * @param contacts
     * @param adminUser
     */
    private void addDepartperson(CWaybillContacts contacts, SysAdminUser adminUser) throws Exception {
        Long waybillId = contacts.getWaybillId();
        CWaybill cWaybill = this.getCWaybillMapper().selectByPrimaryKey(waybillId);
        if (cWaybill == null) {
            LOGGER.info("Waybill is empty");
            throw new BusinessException("运单为空");
        }
        // 1:运单是否为：“已接单” 或 “待提车”
        if (WaybillStatusEnum.ALREADYBID.getValue() == cWaybill.getStatus()
                || WaybillStatusEnum.WAITEXTRACTED.getValue() == cWaybill.getStatus()) {
            // 2:更新运单状态为：“待提车”
            CWaybill waybill = new CWaybill();
            waybill.setId(waybillId);
            waybill.setStatus(WaybillStatusEnum.WAITEXTRACTED.getValue());
            this.getCWaybillMapper().updateByPrimaryKeySelective(waybill);
            // 写运单状态日志
            CWaybillStatusLog log = new CWaybillStatusLog();
            log.setCategory(StatusCategoryEnum.PROCESS.getValue());
            log.setWaybillId(waybillId);
            log.setStatus(WaybillStatusEnum.WAITEXTRACTED.getValue());
            if (adminUser == null) {
                UserVo userVo = this.getUserService().getCurrentUserVo();
                log.setUserId(userVo.getId());
                log.setUserName(userVo.getUsername());
            } else {
                log.setUserId(adminUser.getId());
                log.setUserName(adminUser.getUsername());
            }
            this.getCWaybillStatusLogService().addCWaybillStatusLog(log);

            // 发送 提车安排通知
            CWaybillDetailExample detailExample = new CWaybillDetailExample();
            detailExample.createCriteria().andWaybillIdEqualTo(waybillId).andServiceDispatchTimesEqualTo(1);
            List<CWaybillDetail> details = this.getCWaybillDetailMapper().selectByExample(detailExample);
            List<Long> serviceOrderIdList = new ArrayList<>();
            for (CWaybillDetail cWaybillDetail : details) {
                serviceOrderIdList.add(cWaybillDetail.getServiceOrderId());
            }
            this.getCWaybillService().sendExtractMessage2(serviceOrderIdList, contacts);
        } else {
            LOGGER.info("The current state for waybill : {}", cWaybill.getStatus());
            throw new BusinessException("当前运单状态不是“已接单”或“待提车”状态");
        }
    }

    @Override
    public int addVeneerContacts(CWaybillContacts contacts, SysAdminUser adminUser) {
        LOGGER.info("stanbuss city add driver info contacts : {}, adminUser : {}.", contacts, adminUser);
        // 校验参数
        this.validationInfo(contacts);
        //
        Long id = contacts.getId();
        contacts.setIdno(HYCUtils.encryptBankCard(contacts.getIdno()));
        if (null != id) {
            return this.getCWaybillContactsMapper().updateByPrimaryKeySelective(contacts);
        } else {
            contacts.setCreateTime(new Date());
            contacts.setUpdateTime(new Date());

            List<CWaybillContacts> list = new ArrayList<CWaybillContacts>();
            contacts.setType(WaybillContactsTypeEnum.DRIVER.getValue());
            list.add(contacts);
            LOGGER.info("stanbuss city add driver info contacts : {}, contactsType : {}.", contacts, WaybillContactsTypeEnum.DRIVER.getValue());
            CWaybillContacts cWaybillContacts20 = new CWaybillContacts();
            BeanUtils.copyProperties(contacts, cWaybillContacts20);
            cWaybillContacts20.setType(WaybillContactsTypeEnum.DEPARTPERSON.getValue());
            list.add(cWaybillContacts20);
            LOGGER.info("stanbuss city add driver info contacts : {}, contactsType : {}.", contacts, WaybillContactsTypeEnum.DEPARTPERSON.getValue());
            CWaybillContacts cWaybillContacts30 = new CWaybillContacts();
            BeanUtils.copyProperties(contacts, cWaybillContacts30);
            cWaybillContacts30.setType(WaybillContactsTypeEnum.RECEIPTPERSON.getValue());
            list.add(cWaybillContacts30);
            LOGGER.info("stanbuss city add driver info contacts : {}, contactsType : {}.", contacts, WaybillContactsTypeEnum.RECEIPTPERSON.getValue());

            return this.batchInsert(list);
        }
    }

    private void validationInfo(CWaybillContacts contacts) {
        if (null == contacts.getWaybillId()) {
            LOGGER.info("add driver info wayillId is null");
            throw new BusinessException("运单ID不能为空");
        } else if (StringUtils.isEmpty(contacts.getContact())) {
            LOGGER.info("add driver info contact is null");
            throw new BusinessException("司机姓名不能为空");
        } else if (StringUtils.isEmpty(contacts.getPhone())) {
            LOGGER.info("add driver info phone is null");
            throw new BusinessException("司机电话不能为空");
        } else if (StringUtils.isEmpty(contacts.getIdno())) {
            LOGGER.info("add driver info idno is null");
            throw new BusinessException("司机身份证号不能为空");
        } else if (StringUtils.isEmpty(contacts.getLicenseNumner())) {
            LOGGER.info("add driver info licenseNumber is null");
            throw new BusinessException("司机车牌号不能为空");
        }
    }

}